#include <string.h>
#include <cmath>   
#include <iostream>  //预处理器指令 a PREPROCESSOR directive
#include <vector>
#include <array>

using namespace std; //使定义可见   make definitions visible

/*
  C++ primer 11.2 
  1. 计算时间 运算符重载示例

  如果早上花费了2小时35分钟，下午又花费了2小时40分钟，则总共花了多少时间呢?
  时间相加/相乘
  友元函数

  重载 << 输出对象
*/



class Time
{
	private:
		int hours;
		int minutes;
	public:
		Time();
		Time(int h, int m = 0);
		void AddMin(int m);
		void AddHr(int h);
		void Reset(int h = 0, int m = 0);
    void Show() const; //展示时间

		const Time Sum(const Time & t) const; //常规时间相加方法
    Time operator + (const Time & t) const; //重载加法运算符,实现时间相加

    //多倍时间 调用格式如: time1 * 2; // 不支持2 * time1的格式
    Time operator*(double mult) const;//goes in class declaration
    
    //非成员函数重载*号 , 支持2 * time1的格式
    friend Time operator*(double m,const Time& t);//goes in class declaration
    
    //要为类重载运算符，并将非类的项作为其第一个操作数，则可以用友元函数来反转操作数的顺序。
    //友元函数 friend 可以访问类的私有成员 

    //用cout显示对象  cout << time1; 
    //返回值是ostream& 是为了支持  cout << time1 << " " << time2; 连续调用 
    friend ostream& operator<<(ostream& os,const Time& t);
};



int main(){
 
  Time time1 = Time(1,1);
  Time* time2 = new Time(2,2);
  time2->Show();

  Time time3 = time1.Sum(*time2);
  time3.Show();
  
  Time total = time1.operator+(*time2);

  total = time1 + *time2;

  total.Show();

  total = 4 * time1;
  // total.Show();

  cout << total;

  delete time2;

}


Time::Time()
{
    hours = minutes = 0;
}

Time::Time(int h, int m )
{
    hours = h;
    minutes = m;
}

void Time::AddMin(int m)
{
    minutes += m;
    hours += minutes / 60;
    minutes %= 60;
}

void Time::AddHr(int h)
{
    hours += h;
}

void Time::Reset(int h, int m)
{
    hours = h;
    minutes = m;
}

//常规时间相加
const Time Time::Sum(const Time & t) const
{
    Time sum;
    sum.minutes = minutes + t.minutes;
    sum.hours = hours + t.hours + sum.minutes / 60;
    sum.minutes %= 60;
    return sum;
}

void Time::Show() const
{
    std::cout << hours << " hours, " << minutes << " minutes" << std::endl;
}

Time Time::operator+(const Time & t) const
{
    Time sum;
    sum.minutes = minutes + t.minutes;
    sum.hours = hours + t.hours + sum.minutes / 60;
    sum.minutes %= 60;
    return sum;
}

// void operator<<(ostream& os,const Time& t)
// { 
//   //cout 是ostream的一个对象
// 	 os << " << 重载:  " << t.hours << " hours," << t.minutes <<" minutes";
// }

//因为它不是成员函数，所以不要使用Time::限定符。
ostream& operator<<(ostream& os,const Time& t)
{
	os << t.hours <<" hours,"<< t.minutes <<" minutes";
	return os;
}


Time Time::operator*(double mult) const
{
    Time result;
    long totalminutes = hours * mult * 60 + minutes * mult;
    result.hours = totalminutes / 60;
    result.minutes = totalminutes % 60;
    return result;
}

// 除非函数定义也是原型，否则不能在函数定义中使用该关键字 friend
Time operator*(double mult,const Time& t)//friend not used indefinition
{ 

  // Time result;
  // long totalminutes = t.hours * mult * 60 +  t.minutes * mult;
  // result.hours = totalminutes/60;
  // result.minutes = totalminutes%60;

  //调用成员函数实现功能
  Time result = t * mult;
  return result;
}










